﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using System.Drawing.Design;
using System.ComponentModel.Design;
using System.Workflow.ComponentModel;
using System.Collections;
using System.ComponentModel.Design.Serialization;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Workflow.Activities;
using System.Windows.Forms.Design;
using System.Diagnostics;
using System.Drawing.Text;
using OpenComposite.EII.Repository;
using System.Workflow.ComponentModel.Design;
using System.Reflection;
using OpenComposite.EII.Designer.Workflow;
using OpenComposite.EII.Designer;
using OpenComposite.Repository.Designer.Workflow;

namespace OpenComposite.EII.Services
{
	public partial class MainToolboxService : DockContent, IToolboxService, IRepositoryToolbox
	{
		#region Initialization
		protected MainToolboxService()
		{
			_categories = new List<string>();
			_items = new List<MainToolboxItem>();

			InitializeComponent();

			this.IsHidden = true;
		}
		public MainToolboxService(IServiceProvider provider)
			: this()
		{
			this.provider = provider;

			_surfaceManager = provider.GetService(typeof(RepositorySurfaceManager)) as RepositorySurfaceManager;
			Debug.Assert(_surfaceManager != null);

			_surfaceManager.ActiveDesignSurfaceChanged += new ActiveDesignSurfaceChangedEventHandler(_surfaceManager_ActiveDesignSurfaceChanged);
		}

		#endregion

		#region Public Members

		#region Properties
		public CategoryNameCollection CategoryNames
		{
			get { return new CategoryNameCollection(_categories.ToArray()); }
		}
		public string SelectedCategory
		{
			get
			{
				return _selectedCategory;
			}
			set
			{
				if ( _selectedCategory != value ) {
					string old = _selectedCategory;
					_selectedCategory = value;
					OnSelectedCategoryChanged(old, _selectedCategory);
				}
			}
		}

		#endregion

		#region Events
		#endregion

		#region Methods

		#region IRepositoryToolbox Members
		public void AddItem(ItemType type, string category)
		{
			if ( !_categories.Contains(category) ) {
				_categories.Add(category);
			}
			bool exists = _items.Exists(delegate(MainToolboxItem item)
			{
				return item.ItemType == type && item.Category == category;
			});
			if ( !exists ) {
				_items.Add(new MainToolboxItem(type, category));
			}
		}
		public void AddItem(ItemType typeDiagram, ItemType type, string category)
		{
			if ( !_categories.Contains(category) ) {
				_categories.Add(category);
			}
			bool exists = _items.Exists(delegate(MainToolboxItem item)
			{
				return item.DiagramType == typeDiagram && item.ItemType == type && item.Category == category;
			});
			if ( !exists ) {
				_items.Add(new MainToolboxItem(typeDiagram, type, category));
			}
		}

		public void Clear()
		{
			_items.Clear();
		}
		public void Clear(string category)
		{
			_items.RemoveAll(delegate(MainToolboxItem item)
			{
				return ( item.Category == category );
			});
		}
		#endregion

		#region IToolboxService Members
		public void AddCreator(ToolboxItemCreatorCallback creator, string format)
		{
			AddCreator(creator, format, null);
		}
		public void AddCreator(ToolboxItemCreatorCallback creator, string format, IDesignerHost host)
		{
			if ( creator == null || format == null ) {
				throw new ArgumentNullException(creator == null ? "creator" : "format");
			}

			if ( customCreators == null ) {
				customCreators = new Hashtable();
			} else {
				string key = format;

				if ( host != null ) key += ", " + host.GetHashCode().ToString();

				if ( customCreators.ContainsKey(key) ) {
					throw new Exception("There is already a creator registered for the format '" + format + "'.");
				}
			}

			customCreators[format] = creator;
		}

		public void AddLinkedToolboxItem(ToolboxItem toolboxItem, IDesignerHost host)
		{
		}
		public void AddLinkedToolboxItem(ToolboxItem toolboxItem, string category, IDesignerHost host)
		{
		}

		public virtual void AddToolboxItem(ToolboxItem toolboxItem)
		{
		}
		public virtual void AddToolboxItem(ToolboxItem toolboxItem, IDesignerHost host)
		{
		}
		public virtual void AddToolboxItem(ToolboxItem toolboxItem, string category)
		{
		}
		public virtual void AddToolboxItem(ToolboxItem toolboxItem, string category, IDesignerHost host)
		{
		}

		public virtual ToolboxItem GetSelectedToolboxItem()
		{
			ToolboxItem toolClass = null;
			if ( this.currentSelection != null ) {
				try {
					toolClass = MainToolboxService.GetToolboxItem(this.currentSelection);
				} catch ( TypeLoadException ) {
				}
			}

			return toolClass;
		}
		public virtual ToolboxItem GetSelectedToolboxItem(IDesignerHost host)
		{
			return GetSelectedToolboxItem();
		}

		public object SerializeToolboxItem(ToolboxItem toolboxItem)
		{
			DataObject dataObject = new DataObject();
			dataObject.SetData(typeof(ToolboxItem), toolboxItem);
			return dataObject;
		}

		public ToolboxItem DeserializeToolboxItem(object dataObject)
		{
			return DeserializeToolboxItem(dataObject, null);
		}
		public ToolboxItem DeserializeToolboxItem(object data, IDesignerHost host)
		{
			IDataObject dataObject = data as IDataObject;

			if ( dataObject == null ) {
				return null;
			}

			ToolboxItem t = (ToolboxItem)dataObject.GetData(typeof(ToolboxItem));

			if ( t == null ) {
				string format;
				ToolboxItemCreatorCallback creator = FindToolboxItemCreator(dataObject, host, out format);

				if ( creator != null ) {
					return creator(dataObject, format);
				}
			}

			return t;
		}

		public ToolboxItemCollection GetToolboxItems()
		{
			return new ToolboxItemCollection(new ToolboxItem[0]);
		}
		public ToolboxItemCollection GetToolboxItems(IDesignerHost host)
		{
			return new ToolboxItemCollection(new ToolboxItem[0]);
		}
		public ToolboxItemCollection GetToolboxItems(string category)
		{
			return new ToolboxItemCollection(new ToolboxItem[0]);
		}
		public ToolboxItemCollection GetToolboxItems(string category, IDesignerHost host)
		{
			return new ToolboxItemCollection(new ToolboxItem[0]);
		}

		public bool IsSupported(object data, IDesignerHost host)
		{
			return true;
		}
		public bool IsSupported(object serializedObject, ICollection filterAttributes)
		{
			return true;
		}

		public bool IsToolboxItem(object dataObject)
		{
			return IsToolboxItem(dataObject, null);
		}
		public bool IsToolboxItem(object data, IDesignerHost host)
		{
			IDataObject dataObject = data as IDataObject;
			if ( dataObject == null )
				return false;

			if ( dataObject.GetDataPresent(typeof(ToolboxItem)) ) {
				return true;
			} else {
				string format;
				ToolboxItemCreatorCallback creator = FindToolboxItemCreator(dataObject, host, out format);
				if ( creator != null )
					return true;
			}

			return false;
		}

		public new void Refresh()
		{
		}

		public void RemoveCreator(string format)
		{
			RemoveCreator(format, null);
		}
		public void RemoveCreator(string format, IDesignerHost host)
		{
			if ( format == null )
				throw new ArgumentNullException("format");

			if ( customCreators != null ) {
				string key = format;
				if ( host != null )
					key += ", " + host.GetHashCode().ToString();
				customCreators.Remove(key);
			}
		}

		public virtual void RemoveToolboxItem(ToolboxItem toolComponentClass)
		{
		}
		public virtual void RemoveToolboxItem(ToolboxItem componentClass, string category)
		{
		}

		public virtual bool SetCursor()
		{
			if ( this.currentSelection != null ) {
				Cursor.Current = Cursors.Cross;
				return true;
			}

			return false;
		}

		public virtual void SetSelectedToolboxItem(ToolboxItem selectedToolClass)
		{
			if ( selectedToolClass == null ) {
				lbToolbox.SelectedIndex = 0;
				OnListBoxClick(null, EventArgs.Empty);
			}
		}

		public void AddType(Type t, string category)
		{
			_items.Add(new MainToolboxItem(t.AssemblyQualifiedName, category));
		}

		public Attribute[] GetEnabledAttributes()
		{
			return null;
		}

		public void SetEnabledAttributes(Attribute[] attrs)
		{
		}

		public void SelectedToolboxItemUsed()
		{
			SetSelectedToolboxItem(null);
		}

		public static IDataObject SerializeActivitiesToDataObject(IServiceProvider serviceProvider, ICollection activities)
		{
			// get component serialization service
			ComponentSerializationService css = (ComponentSerializationService)serviceProvider.GetService(typeof(ComponentSerializationService));
			if ( css == null )
				throw new InvalidOperationException("Component Serialization Service is missing.");

			// serialize all activities to the store
			SerializationStore store = css.CreateStore();
			using ( store ) {
				foreach ( Activity activity in activities )
					css.Serialize(store, activity);
			}

			// wrap it with clipboard style object
			Stream stream = new MemoryStream();
			BinaryFormatter formatter = new BinaryFormatter();
			formatter.Serialize(stream, store);
			stream.Seek(0, SeekOrigin.Begin);
			return new DataObject(CF_DESIGNER, stream);
		}

		public static Activity[] DeserializeActivitiesFromDataObject(IServiceProvider serviceProvider, IDataObject dataObj, bool addReference)
		{
			IDesignerHost designerHost = (IDesignerHost)serviceProvider.GetService(typeof(IDesignerHost));
			if ( designerHost == null )
				throw new InvalidOperationException("IDesignerHost is missing.");

			if ( dataObj == null )
				return new Activity[] { };

			object data = dataObj.GetData(CF_DESIGNER);
			ICollection activities = null;
			if ( data is Stream ) {
				BinaryFormatter formatter = new BinaryFormatter();
				( (Stream)data ).Seek(0, SeekOrigin.Begin);
				object serializationData = formatter.Deserialize((Stream)data);
				if ( serializationData is SerializationStore ) {
					// get component serialization service
					ComponentSerializationService css = serviceProvider.GetService(typeof(ComponentSerializationService)) as ComponentSerializationService;
					if ( css == null )
						throw new Exception("ComponentSerializationService is missing.");

					// deserialize data
					activities = css.Deserialize((SerializationStore)serializationData);
				}
			} else {
				// Now check for a toolbox item.
				IToolboxService ts = (IToolboxService)serviceProvider.GetService(typeof(IToolboxService));
				if ( ts != null && ts.IsSupported(dataObj, designerHost) ) {
					ToolboxItem toolBoxItem = ts.DeserializeToolboxItem(dataObj, designerHost);
					if ( toolBoxItem != null ) {
						// this will make sure that we add the assembly reference to project
						if ( addReference && toolBoxItem.AssemblyName != null ) {
							ITypeResolutionService trs = serviceProvider
								.GetService(typeof(ITypeResolutionService)) as ITypeResolutionService;
							if ( trs != null ) trs.ReferenceAssembly(toolBoxItem.AssemblyName);
						}

						ActivityToolboxItem activityToolboxItem = toolBoxItem as ActivityToolboxItem;
						if ( addReference && activityToolboxItem != null )
							activities = activityToolboxItem.CreateComponentsWithUI(designerHost);
						else
							activities = toolBoxItem.CreateComponents(designerHost);
					}
				}
			}

			return ( activities != null ) ? (Activity[])( new ArrayList(activities).ToArray(typeof(Activity)) ) : new Activity[] { };
		}

		#endregion

		/// <summary>
		/// Gets the toolbox item associated with a component type
		/// </summary>
		internal static ToolboxItem GetToolboxItem(Type toolType)
		{
			if ( toolType == null ) throw new ArgumentNullException("toolType");

			ToolboxItem item = null;
			if ( ( toolType.IsPublic || toolType.IsNestedPublic ) &&
				 typeof(IComponent).IsAssignableFrom(toolType) && !toolType.IsAbstract ) {
				ToolboxItemAttribute toolboxItemAttribute = (ToolboxItemAttribute)TypeDescriptor
					.GetAttributes(toolType)[typeof(ToolboxItemAttribute)];
				if ( toolboxItemAttribute != null && !toolboxItemAttribute.IsDefaultAttribute() ) {
					Type itemType = toolboxItemAttribute.ToolboxItemType;
					if ( itemType != null ) {
						// First, try to find a constructor with Type as a parameter.  If that
						// fails, try the default constructor.
						ConstructorInfo ctor = itemType.GetConstructor(new Type[] { typeof(Type) });
						if ( ctor != null ) {
							item = (ToolboxItem)ctor.Invoke(new object[] { toolType });
						} else {
							ctor = itemType.GetConstructor(new Type[0]);
							if ( ctor != null ) {
								item = (ToolboxItem)ctor.Invoke(new object[0]);
								item.Initialize(toolType);
							}
						}
					}
				} else if ( !toolboxItemAttribute.Equals(ToolboxItemAttribute.None) ) {
					item = new ToolboxItem(toolType);
				}
			} else if ( typeof(ToolboxItem).IsAssignableFrom(toolType) ) {
				// if the type *is* a toolboxitem, just create it..
				//
				try {
					item = (ToolboxItem)Activator.CreateInstance(toolType, true);
				} catch {
				}
			}

			return item;
		}
		#endregion

		#endregion

		#region Protected Members

		#region Methods
		protected void OnSelectedCategoryChanged(string oldCategory, string newCategory)
		{
			Debug.WriteLine("old: " + oldCategory + "; new: " + newCategory);
			lbToolbox.Items.Clear();
			lbToolbox.BeginUpdate();
			foreach ( var item in _items ) {
				if ( newCategory == item.Category ) {
					Debug.WriteLine("Category: " + item.Category + " - " + item.ToString());
					lbToolbox.Items.Add(item);
				}
			}
			if ( lbToolbox.Items.Count == 0 ) {
				lbToolbox.Items.Add("No Toolbox Available");
			}
			lbToolbox.EndUpdate();
		}
		#endregion

		#endregion

		#region Private Members

		#region Constants
		private const string CF_DESIGNER = "CF_WINOEDESIGNERCOMPONENTS";
		#endregion

		#region Fields
		private IServiceProvider provider;
		private Hashtable customCreators;
		private Type currentSelection;
		private RepositorySurfaceManager _surfaceManager;
		private List<string> _categories;
		private string _selectedCategory;
		private List<MainToolboxItem> _items;
		#endregion

		#region Methods
		private ToolboxItemCreatorCallback FindToolboxItemCreator(IDataObject dataObj, IDesignerHost host, out string foundFormat)
		{
			foundFormat = string.Empty;

			ToolboxItemCreatorCallback creator = null;
			if ( customCreators != null ) {
				IEnumerator keys = customCreators.Keys.GetEnumerator();
				while ( keys.MoveNext() ) {
					string key = (string)keys.Current;
					string[] keyParts = key.Split(new char[] { ',' });
					string format = keyParts[0];

					if ( dataObj.GetDataPresent(format) ) {
						// Check to see if the host matches.
						if ( keyParts.Length == 1 || ( host != null && host.GetHashCode().ToString().Equals(keyParts[1]) ) ) {
							creator = (ToolboxItemCreatorCallback)customCreators[format];
							foundFormat = format;
							break;
						}
					}
				}
			}

			return creator;
		}
		/// <summary>
		/// Parse the toolbox.txt file embedded in resource and create the entries in toolbox
		/// </summary>
		/// <returns>Returns the category of the new added items.</returns>
		private string AddToolboxEntries(WorkflowLoader loader, ListBox lb)
		{
			Stream selfTools;
			string category = null;
			if ( loader != null ) {
				//selfTools = GetType().Module.Assembly.GetManifestResourceStream(GetType(), "ToolboxItems_BProcess.txt");
				if ( loader.Workflow.Type == OpenComposite.EII.Repository.WorkflowType.Business_Process ||
					 loader.Workflow.Type == OpenComposite.EII.Repository.WorkflowType.Mashup_Horizontal ) {
					selfTools = loader.GetType().Module.Assembly.GetManifestResourceStream(typeof(toolboxfinder), "ToolboxItems_BProcess.txt");
					category = "Business Process";
				} else {
					selfTools = loader.GetType().Module.Assembly.GetManifestResourceStream(typeof(toolboxfinder), "ToolboxItems.txt");
					category = "Workflow";
				}
			} else {
				selfTools = GetType().Module.Assembly.GetManifestResourceStream(typeof(toolboxfinder), "ToolboxItems.txt");
				category = "Workflow";
			}
			Debug.Assert(selfTools != null, "Unable to load ToolboxItems.txt for type '" + GetType().FullName + "'");
			if ( !this.CategoryNames.Contains(category) ) {
				int len = (int)selfTools.Length;
				byte[] bytes = new byte[len];
				selfTools.Read(bytes, 0, len);

				string entries = Encoding.Default.GetString(bytes);

				int start = 0, end = 0;
				lb.Items.Clear();
				string entry;
				while ( end < entries.Length ) {
					end = entries.IndexOf('\r', start);
					if ( end == -1 ) end = entries.Length;

					entry = entries.Substring(start, ( end - start ));
					if ( entry.Length != 0 && !entry.StartsWith(";") ) {
						_items.Add(new MainToolboxItem(entry, category));
					}
					start = end + 2;
				}
			}
			return category;
		}
		#endregion

		#region Event Handlers
		private void OnDrawItem(object sender, DrawItemEventArgs e)
		{
			if ( e.Index < 0 ) {
				return;
			}


			Graphics g = e.Graphics;
			ListBox listBox = (ListBox)sender;
			object objItem = listBox.Items[e.Index];
			MainToolboxItem item = null;
			Bitmap bitmap = null;
			string text = null;

			if ( objItem is string ) {
				bitmap = null;
				text = (string)objItem;
			} else {
				item = (MainToolboxItem)objItem;
				bitmap = (Bitmap)item.Image; // if it's not a bitmap, it's a metafile, and how likely is that?
				text = item.DisplayName;
			}

			if ( item != null && item.ItemType == ItemType.Separator ) {
				int y = e.Bounds.Y + (int)( e.Bounds.Height / 2 );
				g.DrawLine(SystemPens.ControlDarkDark, e.Bounds.Left, y, e.Bounds.Right, y);
			} else {
				bool selected = false;
				bool disabled = false;

				if ( ( e.State & DrawItemState.Selected ) == DrawItemState.Selected ) {
					selected = true;
				}
				if ( (int)( e.State & ( DrawItemState.Disabled | DrawItemState.Grayed | DrawItemState.Inactive ) ) != 0 ) {
					disabled = true;
				}

				StringFormat format = new StringFormat();
				format.HotkeyPrefix = HotkeyPrefix.Show;
				format.Trimming = StringTrimming.EllipsisCharacter;
				format.LineAlignment = StringAlignment.Center;
				format.FormatFlags = StringFormatFlags.NoWrap;

				int x = e.Bounds.X + 4;
				x += 20;


				g.FillRectangle(SystemBrushes.Control, e.Bounds);
				if ( selected ) {
					Rectangle r = e.Bounds;
					r.Width--; r.Height--;
					g.FillRectangle(new SolidBrush(Color.FromArgb(64, SystemColors.Highlight)), r);
					g.DrawRectangle(SystemPens.Highlight, r);
				} else {

					//using ( Brush border = new SolidBrush(Color.FromArgb(Math.Min(SystemColors.Control.R + 15, 255), Math.Min(SystemColors.Control.G + 15, 255), Math.Min(SystemColors.Control.B + 15, 255))) )
					//    g.FillRectangle(border, new Rectangle(e.Bounds.X, e.Bounds.Y, 20, e.Bounds.Height));
				}

				if ( bitmap != null ) {
					g.DrawImage(bitmap, e.Bounds.X + 2, e.Bounds.Y + 2, bitmap.Width, bitmap.Height);
				}

				Brush textBrush = ( disabled ) ?
					new SolidBrush(Color.FromArgb(120, SystemColors.MenuText)) :
					SystemBrushes.FromSystemColor(SystemColors.MenuText);
				RectangleF textRect = (RectangleF)e.Bounds;
				textRect.Width -= 20;
				textRect.X += 20;
				g.DrawString(text, Font, textBrush, textRect, format);
				if ( disabled ) textBrush.Dispose();
				format.Dispose();
			}
		}

		//Start the drag drop when user selects and drags the tool
		private void OnListBoxMouseMove(object sender, MouseEventArgs e)
		{
			ListBox listBox = (ListBox)sender;
			if ( e.Button == MouseButtons.Left && listBox.SelectedItem != null ) {
				MainToolboxItem selectedItem = listBox.SelectedItem as MainToolboxItem;

				if ( selectedItem == null || selectedItem.ItemType == ItemType.Separator ) return;

				if ( selectedItem.ComponentClass == null ) {
					DragDropEffects effects = DoDragDrop(selectedItem.ItemType,
														 DragDropEffects.Copy | DragDropEffects.Move);
				} else {
					ToolboxItem toolboxItem = MainToolboxService.GetToolboxItem(selectedItem.ComponentClass);
					IDataObject dataObject = this.SerializeToolboxItem(toolboxItem) as IDataObject;
					DragDropEffects effects = DoDragDrop(dataObject, DragDropEffects.Copy | DragDropEffects.Move);
				}
			}
		}

		private void OnListBoxClick(object sender, EventArgs eevent)
		{
			MainToolboxItem toolboxItem = lbToolbox.SelectedItem as MainToolboxItem;
			if ( toolboxItem != null ) {
				this.currentSelection = toolboxItem.ComponentClass;
			} else if ( this.currentSelection != null ) {
				int index = this.lbToolbox.Items.IndexOf(this.currentSelection);
				if ( index >= 0 )
					this.lbToolbox.SelectedIndex = index;
			}
		}
		private void OnListBoxDoubleClick(object sener, EventArgs e)
		{
			IToolboxUser docDes = null;
			MainToolboxItem selectedItem = lbToolbox.SelectedItem as MainToolboxItem;
			if ( selectedItem == null )
				return;

			this.currentSelection = selectedItem.ComponentClass;
			IDesignerHost host = (IDesignerHost)provider.GetService(typeof(IDesignerHost));//des.ActiveDesigner;
			if ( host != null && this.currentSelection != null ) {
				IDesigner designer = host.GetDesigner(host.RootComponent);
				if ( designer is IToolboxUser )
					docDes = (IToolboxUser)designer;

				if ( docDes != null ) {
					ToolboxItem c = MainToolboxService.GetToolboxItem(this.currentSelection);
					Debug.Assert(c != null, "Class " + this.currentSelection.FullName + " does not exist");
					if ( c != null && docDes.GetToolSupported(c) ) {
						try {
							docDes.ToolPicked(c);
						} catch ( Exception ex ) {
							IUIService uis = (IUIService)provider.GetService(typeof(IUIService));

							if ( uis != null ) {
								uis.ShowError(ex);
							} else {
								MessageBox.Show("Error: " + ex.ToString());
							}
						}
					}
				} else {
					object o = Activator.CreateInstance(this.currentSelection);
					SequentialWorkflowActivity service = host.RootComponent as SequentialWorkflowActivity;
					service.Activities.Add(o as Activity);
					host.RootComponent.Site.Container.Add(o as IComponent);
				}
			}
		}

		private void OnListKeyPress(object sender, KeyPressEventArgs e)
		{
			if ( e.KeyChar == 0xD ) {
				OnListBoxDoubleClick(sender, e);
				e.Handled = true;
			}
		}

		private Rectangle _hotTracked = Rectangle.Empty;
		private void lbToolbox_MouseHover(object sender, EventArgs e)
		{
		}

		private void _surfaceManager_ActiveDesignSurfaceChanged(object sender, ActiveDesignSurfaceChangedEventArgs e)
		{
			if ( e.NewSurface == null ) {
				this.SelectedCategory = null;
				this.IsHidden = true;
				return;
			}
			WorkflowLoader loader = e.NewSurface.GetService(typeof(WorkflowDesignerLoader)) as WorkflowLoader;
			RepositorySurface rs = e.NewSurface as RepositorySurface;
			if ( rs != null && rs.Controller != null ) {
				this.SelectedCategory = rs.Controller.ToolboxCategory;
				this.Show();
			}
			if ( loader != null ) {
				string category = AddToolboxEntries(loader, lbToolbox);
				if ( !_categories.Contains(category) ) {
					_categories.Add(category);
				}
				WorkflowController wfc = rs.Controller as WorkflowController;
				if ( wfc != null ) {
					this.SelectedCategory = string.IsNullOrEmpty(wfc.ToolboxCategory) ? category : wfc.ToolboxCategory;
				} else {
					this.SelectedCategory = category;
				}
			}
		}
		#endregion

		#endregion

		//Create the toolbox and add the toolbox entries
		//public ToolboxService(IServiceProvider provider)
		//{
		//this.provider = provider;

		//Text = "Toolbox";
		//Size = new System.Drawing.Size(224, 350);

		//listBox.Dock = DockStyle.Fill;
		//listBox.IntegralHeight = false;
		//listBox.ItemHeight = 20;
		//listBox.DrawMode = DrawMode.OwnerDrawFixed;
		//listBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
		//listBox.BackColor = SystemColors.Control;
		//listBox.ForeColor = SystemColors.ControlText;
		//listBox.MouseMove +=new MouseEventHandler(OnListBoxMouseMove);
		//Controls.Add(listBox);

		//listBox.DrawItem += new DrawItemEventHandler(this.OnDrawItem);
		//listBox.KeyPress += new KeyPressEventHandler(this.OnListKeyPress);
		//listBox.SelectedIndexChanged += new EventHandler(this.OnListBoxClick);
		//listBox.DoubleClick += new EventHandler(this.OnListBoxDoubleClick);

		//AddToolboxEntries(listBox);
		//}
	}

	class ListBoxEx : ListBox
	{
		protected override void OnPaint(PaintEventArgs e)
		{
			base.OnPaint(e);
		}

		protected override void OnDrawItem(DrawItemEventArgs e)
		{

			base.OnDrawItem(e);
		}
	}
}
